﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Architecture.BusinessLayer;
using CommonComponents.ExceptionHandling;
using LASLogic.BusinessLayer.DataModel;
using LASLogic.DataLayer.Implementor;

namespace LASLogic.BusinessLayer.Requestor
{
    /// <summary>
    /// Clase que maneja las operaciones con las cuentas
    /// </summary>
    public class AccountRequestor : IRequestor
    {

        /// <summary>
        /// Metodo que permite añadir una nueva cuenta a la base de datos
        /// </summary>
        /// <returns>Booleano indicando el estado de la insercion</returns>
        public bool InsertNewAccount(Account account)
        {
            return AccountDataManager.GetInstance().InsertNewAccount(account.AccountCode, account.AccountName, account.ForeignName,
                                                                     account.ParentAccountId, account.Currency.CurrencyId,
                                                                     account.AccountCatalogId);
        }

        /// <summary>
        /// Metodo que permite cambiar el estado de una cuenta
        /// </summary>
        /// <param name="accountId">Id de la cuenta</param>
        /// <param name="status">Nuevo estado de la cuenta</param>
        public bool ChangeAccountStatus(int accountId, string status)
        {
            return AccountDataManager.GetInstance().ChangeAccountStatus(accountId, status);
        }

        /// <summary>
        /// Permite borrar una cuenta del catálogo de cuentas
        /// </summary>
        /// <param name="accountId">Cuenta a borrar</param>
        /// <returns>Booleano indicando el estado del borrado</returns>
        public bool EraseAccount(int accountId)
        {
            return AccountDataManager.GetInstance().EraseAccount(accountId);
        }

        /// <summary>
        /// Permite obtener el catalogo de cuentas de la base de datos
        /// </summary>
        /// <param name="companyId">Identificador de la compañia</param>
        /// <returns>Catalogo de cuentas de una compañia</returns>
        public AccountCatalog GetAccountingCatalog(int companyId)
        {
            return AccountDataManager.GetInstance().GetAccountingCatalog(companyId);
        }

        /// <summary>
        /// Permite insertar el catalogo de cuentas de una compañia
        /// </summary>
        /// <param name="companyId">Identificador de la compañia la cual se quiere insertar el catálogo</param>
        /// <returns>El id del catalogo contable</returns>
        public int InsertAccountingCatalog(int companyId)
        {
            return AccountDataManager.GetInstance().InsertAccountingCatalog(companyId);
        }



        /// <summary>
        /// Metodo que permite insertar un periodo contabl
        /// </summary>
        /// <param name="companyId">Identificador de la compañia</param>
        /// <param name="accountingPeriod">Periodo a insertar</param>
        public bool InsertAccountingPeriod(int companyId, AccountingPeriod accountingPeriod)
        {
            return AccountDataManager.GetInstance().InsertAccountingPeriod(companyId, accountingPeriod.AccountingPeriodType, accountingPeriod.Description);
        }

        /// <summary>
        /// Permite insertar un nuevo período de tiempo para una tasa de cambio
        /// </summary>
        /// <param name="companyId">Identificador de la compañia la cual se quiere insertar el catálogo</param>
        /// <param name="currencyIdDestiny">Identificador de la moneda correspondiente a la tasa de cambio</param>
        /// <param name="startDate">Fecha inicial en la que estará vigente el tipo de cambio</param>
        /// <param name="finishDate">Fecha final en la que estará vigente el tipo de cambio</param>
        /// <param name="exchangeRate">Valor del tipo de cambio</param>
        /// <param name="currencyIdBegining"></param>
        /// <returns>El id del catalogo contable</returns>
        public bool InsertExchangeRate(int companyId, int currencyIdBegining, int currencyIdDestiny, DateTime startDate, DateTime finishDate,
                                      decimal exchangeRate)
        {
            return AccountDataManager.GetInstance().InsertExchangeRate(companyId, currencyIdBegining, currencyIdDestiny, startDate, finishDate,
                                                                       exchangeRate);
        }


        /// <summary>
        /// Permite obtener los estados para un pais
        /// </summary>
        /// <param name="companyId">Identificador de la compania</param>
        /// <param name="currencyIdBegining">Nombre de la moneda que se quiere obtener el tipo de cambio</param>
        /// <param name="currencyIdDestiny">Nombre de la moneda destino que se quiere obtener el tipo de cambio</param>
        /// <param name="fechaActual">Fecha que se quiere averiguar el tipo de cambio de las monedas</param>
        /// <returns>Retorna una lista de estados</returns>
        public decimal GetExchangeRate(int companyId, int currencyIdBegining, int currencyIdDestiny, DateTime fechaActual)
        {
            return AccountDataManager.GetInstance().GetExchangeRate(companyId, currencyIdBegining,
                                                                    currencyIdDestiny, fechaActual);
        }
        
        /// <summary>
        /// Permite obtener todas las monedas de la base de datos
        /// </summary>
        /// <returns>Lista de monedas de la base de datos</returns>
        public List<Currency> GetCurrencies()
        {
            return AccountDataManager.GetInstance().GetCurrencies();
        }

        /// <summary>
        /// Permite insertar una nueva moneda
        /// </summary>
        /// <param name="currency">Moneda a insertar</param>
        /// <returns>Si se logró efectuar correctamente</returns>
        public bool InsertCurrency(Currency currency)
        {
            return AccountDataManager.GetInstance().InsertCurrency(currency.CurrencyName, currency.CurrencyMnemonic);
        }

        /// <summary>
        /// Permite cambiar la moneda a una cuenta
        /// </summary>
        /// <param name="accountId">identificador de la cuenta</param>
        /// <param name="currencyName">nombre de la moneda</param>
        /// <returns>Booleano si se cambia la moneda</returns>
        public bool ChangeAccountCurrency(int accountId, string currencyName)
        {
            return AccountDataManager.GetInstance().ChangeAccountCurrency(accountId, currencyName);
        }

        /// <summary>
        /// Permite cambiar la información de una cuenta
        /// </summary>
        /// <param name="account">Cuenta a ser modificada</param>
        /// <returns>Booleano si se cambia la moneda</returns>
        public bool ChangeAccountInformation(Account account)
        {
            return AccountDataManager.GetInstance().ChangeAccountInformation(account.AccountId, account.AccountName, account.ForeignName, account.Currency.CurrencyName);
        }


        #region Singleton

        /// <summary>
        /// Única instancia de esta clase
        /// </summary>
        private static AccountRequestor _instance;

        /// <summary>
        /// Constructor de la clase
        /// </summary>
        protected AccountRequestor()
        {

        }

        /// <summary>
        /// Método para implementar el patrón de Singleton
        /// </summary>
        /// <returns>Instancia única de la clase</returns>
        public static AccountRequestor GetInstance()
        {
            if (_instance == null)
                _instance = new AccountRequestor();
            return _instance;
        }

        #endregion
    }
}
